<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/stores/index.js'
import { ImagePreview, Toast } from "vant";
import api from "@/api/api";
import { vw } from "@/utils/common";

// 引入图片资源
import avatar2Icon from '@/assets/common/avatar_2.png'

// 响应式数据
const list = ref([])
const loading = ref(false)
const finished = ref(true)
const refreshing = ref(false)
const message = ref("")
const showPic = ref(false)
const fileList = ref([])
const pageInfo = ref({
  pageNum: 1,
  pageSize: 20,
})
const sendFlag = ref(false)
const timer = ref(null)

// DOM引用
const scrollContainer = ref(null)

// 路由和状态管理
const route = useRoute()
const router = useRouter()
const store = useUserStore()

// 获取用户数据
const userData = computed(() => store.setUserData)

// 计算属性
const mainHeight = computed(() => {
  if (showPic.value) {
    return `calc(100vh - ${vw(47)} - ${vw(160)})`
  }
  return `calc(100vh - ${vw(47)} - ${vw(80)})`
})

// 方法定义
const onClickLeft = () => {
  router.back()
}

const picShow = () => {
  if (sendFlag.value) return
  showPic.value = !showPic.value
  setTimeout(() => {
    scrollToBottom()
  }, 200)
}

const onLoad = () => {
  if (refreshing.value) {
    list.value = []
    refreshing.value = false
  }
  getMessageList()
}

const onRefresh = () => {
  // 清空列表数据
  refreshing.value = true
  // 重新加载数据
  // 将 loading 设置为 true，表示处于加载状态
  loading.value = true
  onLoad()
}

// 时间间隔判断（小于1分钟不显示）
const shouldShowTime = (currentMsg, index) => {
  if (index === 0) return true
  let prevTime = new Date(list.value[index - 1].createTime).getTime()
  let currentDate = new Date(currentMsg.createTime).getTime()
  return currentDate - prevTime > 2 * 60 * 1000
}

// 动态时间格式化
const formatChatTime = (timestamp) => {
  const now = new Date()
  const msgDate = new Date(timestamp)
  const diffDays = Math.floor((now - msgDate) / (1000 * 3600 * 24))

  // 规则判断
  if (msgDate.getFullYear() !== now.getFullYear()) {
    return formatDate(msgDate, "yyyy-MM-dd hh:mm")
  } else if (diffDays > 7) {
    return formatDate(msgDate, "MM-dd hh:mm")
  } else if (msgDate.toDateString() !== now.toDateString()) {
    return `${getWeekDay(msgDate)} ${formatDate(msgDate, "hh:mm")}`
  } else {
    return formatDate(msgDate, "hh:mm")
  }
}

// 通用日期格式化
const formatDate = (date, fmt) => {
  const o = {
    "M+": date.getMonth() + 1,
    "d+": date.getDate(),
    "h+": date.getHours(),
    "m+": date.getMinutes(),
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      date.getFullYear().toString().slice(-RegExp.$1.length)
    )
  }
  for (const k in o) {
    const regex = new RegExp(`(${k})`)
    if (regex.test(fmt)) {
      fmt = fmt.replace(regex, (match) =>
        match.length === 1 ? o[k] : o[k].toString().padStart(2, "0")
      )
    }
  }
  return fmt
}

// 获取星期
const getWeekDay = (date) => {
  const weekDays = ["日", "一", "二", "三", "四", "五", "六"]
  return `周${weekDays[date.getDay()]}`
}

const onSend = async () => {
  if (sendFlag.value) return
  if (message.value.trim().length == 0) {
    Toast("不能发送空消息")
  } else {
    sendFlag.value = true
    let params = {
      accountType: 0,
      storeId: 1,
      text: message.value,
      type: 0,
      fileUrl: "",
    }
    if (fileList.value.length) {
      params.type = 1
    }
    list.value.push({
      userId: userData.value.id,
      storeId: params.storeId,
      sendType: 1,
      type: params.type,
      text: message.value,
      flleUrl: params.fileUrl,
      sendUserName: userData.value.userName,
      sendUserAvatar: userData.value.avatar,
      createTime: Date.now(),
      loading: true,
      dev: true,
    })
    setTimeout(() => {
      message.value = ""
    }, 200)
    scrollToBottom() // 替换原有的$nextTick逻辑
    await api.message.sendMessage(params).finally(() => {
      list.value[list.value.length - 1].loading = false
      sendFlag.value = false
    })
  }
}

const imagePreview = (src) => {
  ImagePreview([src])
}

const afterRead = async (file) => {
  let data = new FormData()
  data.append("file", file.file)
  let res = await api.common.upload(data)
  let params = {
    accountType: 0,
    storeId: 1,
    text: "",
    type: 1,
    fileUrl: res,
  }
  list.value.push({
    userId: userData.value.id,
    storeId: params.storeId,
    sendType: 1,
    type: params.type,
    text: message.value,
    flleUrl: params.fileUrl,
    sendUserName: userData.value.userName,
    sendUserAvatar: userData.value.avatar,
    createTime: Date.now(),
    loading: true,
    dev: true,
  })
  scrollToBottom()
  setTimeout(() => {
    showPic.value = !showPic.value
  }, 200)
  await api.message.sendMessage(params).finally(() => {
    list.value[list.value.length - 1].loading = false
    sendFlag.value = false
  })
}

const getMessageList = async () => {
  let parmas = {
    ...pageInfo.value,
    storeId: 1,
  }
  let res = await api.message.getMessageList(parmas)
  list.value = [...list.value, ...res.data].filter((item) => !item.dev)
  const uniqueMap = new Map(list.value.map((item) => [item.autoId, item]))
  list.value = Array.from(uniqueMap.values())
  scrollToBottom() // 替换原有的$nextTick逻辑
  if (res.data.length < pageInfo.value.pageSize) {
    finished.value = true
  } else {
    pageInfo.value.pageNum++
    await getMessageList()
  }
}

const scrollToBottom = () => {
  nextTick(() => {
    const container = scrollContainer.value
    if (container.scrollHeight <= container.clientHeight) {
      return // 内容不足一屏时不滚动
    }
    if (container) {
      // 获取容器实际样式（包含padding）
      const style = window.getComputedStyle(container)
      const paddingBottom = parseFloat(style.paddingBottom) || 0

      // 计算正确的滚动位置（包含padding补偿）
      const scrollPosition =
        container.scrollHeight - container.clientHeight + paddingBottom
      // 计算正确的滚动位置：滚动高度 - 容器可视高度 + 底部padding
      container.scrollTo({
        top: scrollPosition,
        behavior: "smooth",
      })
    }
  })
}

// 生命周期钩子
onMounted(() => {
  onLoad()
  setTimeout(() => {
    timer.value = setInterval(() => {
      getMessageList()
    }, 10000)
  }, 10000)

  if (/iOS/i.test(navigator.userAgent)) {
    // 注意：原代码中的this.$refs.input在重构中已被移除，因为没有实际使用
    // 如果需要处理输入框焦点，需要添加相应的ref引用
  }
})

onBeforeUnmount(() => {
  clearInterval(timer.value)
})
</script>

<template>
  <div class="customer">
    <van-nav-bar title="客服消息" class="nav_bar" fixed @click-left="onClickLeft">
    </van-nav-bar>
    <div class="main" ref="scrollContainer" :style="{ height: mainHeight }">
      <van-pull-refresh v-model:loading="refreshing" disabled @refresh="onRefresh" pulling-text="加载更多历史消息"
        loading-text="请稍等" loosing-text="下拉即可加载更多">
        <van-list v-model:loading="loading" :finished="finished" finished-text="">
          <div v-for="(v, i) in list" :key="JSON.stringify(v) + i" class="chat_container">
            <div v-if="shouldShowTime(v, i)" class="time">
              {{ formatChatTime(v.createTime) }}
            </div>
            <div class="chat_item" :class="{ system: v.sendType == 3, user: v.sendType == 1 }">
              <van-image class="avatar" fit="cover" round :src="v.sendType == 3
                ? avatar2Icon
                : v.sendUserAvatar
                " />
              <div class="right">
                <div class="username">
                  {{ v.sendType == 3 ? "客服" : "我" }}
                </div>
                <div v-if="v.type == 0" class="message">
                  <div class="text_2">
                    {{ v.text }}
                  </div>
                </div>
                <div v-if="v.type == 1" class="message">
                  <van-image class="message_pic" @click="imagePreview(v.fileUrl)" @load="scrollToBottom()"
                    :src="v.fileUrl">
                    <template #loading>
                      <van-loading type="spinner" size="20" />
                    </template>
                  </van-image>
                </div>
              </div>
              <van-loading v-if="v.loading" />
            </div>
          </div>
        </van-list>
      </van-pull-refresh>
    </div>
    <div class="input_container">
      <div class="input">
        <van-icon name="add-o" class="input_add" @click="picShow" />
        <van-search v-model="message" show-action placeholder="请输入您想咨询的内容">
          <template #action>
            <div @click="onSend" class="search_btn">发送</div>
          </template>
        </van-search>
      </div>
      <div class="other_container" :class="{ add_active: showPic }">
        <van-uploader max-count="1" :preview-image="false" :after-read="afterRead">
          <van-grid :border="false">
            <van-grid-item icon="photo-o" text="相册" />
          </van-grid>
        </van-uploader>
      </div>
    </div>
  </div>
</template>



<style lang="less" scoped>
.customer {
  min-height: 100vh;
  background: url("https://zxcxappimg.oss-cn-hangzhou.aliyuncs.com//zxcxmall/2025/05/29/4431a33cd62f4efc9fc53a7606eee382.png") no-repeat;
  background-size: cover;
  background-attachment: fixed;
  background-position: center;
  box-sizing: border-box;
  padding: 200px 50px 220px 50px;
  overflow: hidden;

  :deep(.van-nav-bar__content) {
    height: 100px;
    margin: 25px auto;
  }

  :deep(.van-nav-bar__title) {
    font-size: 54px;
    font-weight: 500;
  }

  :deep(.van-ellipsis) {
    overflow: initial;
  }

  .main {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    will-change: transform;

    .chat_container {
      display: flex;
      flex-direction: column;

      .time {
        width: 100%;
        font-size: 44px;
        color: #333;
        text-align: center;
      }

      .chat_item {
        display: flex;
        align-items: start;
        width: 100%;
        margin: 40px 0;

        .avatar {
          min-width: 150px;
          max-width: 150px;
          height: 150px;
        }

        .right {
          .username {
            font-size: 45px;
            color: #888888;
            margin-bottom: 15px;
          }

          .message {
            padding: 30px 25px;
            border-radius: 20px;
            flex-grow: 1;

            .text_2 {
              font-size: 44px;
              color: #666666;
            }
          }

          .message_pic {
            max-width: 600px;
            object-fit: contain;
          }
        }
      }

      .system {
        justify-content: start;

        .right {
          margin-left: 30px;

          .message {
            background: #fff;
          }
        }
      }

      .user {
        flex-direction: row-reverse;

        .right {
          margin-right: 30px;

          .username {
            text-align: right;
          }

          .message {
            background: #406dfc;

            .text_2 {
              color: #fff;
            }
          }
        }
      }
    }
  }

  .input_container {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 30px 30px 90px 30px;
    background: #fff;
    z-index: 99;

    .input {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .input_add {
        font-size: 60px;
        margin-right: 25px;
      }

      :deep(.van-search) {
        padding: 0;
        flex-grow: 1;
      }

      .search_btn {
        font-size: 38px;
        padding: 0 40px;
        background: #406dfc;
        border-radius: 10px;
        height: 100px;
        line-height: 100px;
        color: #fff;
      }
    }

    .other_container {
      width: 100%;
      height: 0;
      transition: all 1s;
      display: none;
    }

    .add_active {
      display: flex;
      height: 250px;
    }
  }
}

:deep(.van-search__field) {
  height: 100px;
}

:deep(.van-field__left-icon .van-icon) {
  font-size: 60px;
}

:deep(.van-cell__value) {
  font-size: 44px;
}

:deep(.van-grid-item__icon) {
  font-size: 120px;
}

:deep(.van-grid-item__text) {
  font-size: 44px;
}
</style>
